package com.qbccn.oauth2service.controller;

import com.qbccn.dto.CodeStatus;
import com.qbccn.dto.ResponseResult;
import com.qbccn.oauth2service.domain.SsoUser;
import com.qbccn.oauth2service.feign.OauthServiceFeign;
import com.qbccn.oauth2service.service.UserService;
import com.qbccn.utils.MapUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.token.ConsumerTokenServices;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Api(tags = "oauth2-api")
@RestController
@RequestMapping("oauth")
public class Oauth2Controller {

    @Value("${sso.oauth2.grant_type}")
    public String oauth2GrantType;
    @Value("${sso.oauth2.client_id}")
    public String oauth2ClientId;
    @Value("${sso.oauth2.client_secret}")
    public String oauth2ClientSecret;

    @Autowired
    private UserService userService;
    @Autowired
    private ConsumerTokenServices consumerTokenServices;
    @Autowired
    private OauthServiceFeign oauthServiceFeign;

    @ApiOperation(value = "登陆接口", notes = "根据账号密码登陆获取token")
    @PostMapping("/user/login")
    public ResponseResult login(String username, String password) {
        SsoUser user = userService.getUserInfo(username);
        if (user == null || !user.getPassword().equals(password)) {
            return new ResponseResult(CodeStatus.FAIL, "账号或密码错误！");
        } else if (user.getStatus() != 1) {
            //0、无效，1、有效，2、冻结，3、其他
            if (user.getStatus() == 0)
                return new ResponseResult(CodeStatus.FAIL, "当前账号无效！");
            if (user.getStatus() == 2)
                return new ResponseResult(CodeStatus.FAIL, "当前账号被冻结！");
        }
        try {
            // 解析响应结果封装并返回
            // 使用feign获取token
            String res = oauthServiceFeign.login(username, password, oauth2GrantType, oauth2ClientId, oauth2ClientSecret);
            Map<String, Object> jsonMap = MapUtils.json2map(res);
            String token = String.valueOf(jsonMap.get("access_token"));
            Map<String, String> result = new HashMap<>();
            result.put("token", token);
            return new ResponseResult(CodeStatus.OK, "登录成功", result);
        } catch (Exception e) {
            return new ResponseResult(CodeStatus.FAIL, "登录异常");
        }
    }

    @PostMapping("/user/refreshToken")
    public ResponseResult refreshToken(String refreshToken) {
        if (StringUtils.isEmpty(refreshToken))
            return new ResponseResult(CodeStatus.FAIL, "无refreshToken参数");
        try {
            // 刷新令牌：grant固定为 refresh_token
            String res = oauthServiceFeign.refreshToken(refreshToken,
                    "refresh_token", oauth2ClientId, oauth2ClientSecret);
            System.out.println(res);
        } catch (Exception e) {
            return new ResponseResult(CodeStatus.FAIL, "刷新令牌异常");
        }
        return null;
    }

    @ApiOperation(value = "注销接口", notes = "根据传来的token进行注销操作")
    @GetMapping("/user/logout")
    @RequestMapping(value = "/user/logout", method = {RequestMethod.GET, RequestMethod.POST})
    public ResponseResult<Void> logout1(HttpServletRequest request) {
        // 获取 token
        String token = request.getParameter("access_token");
        if (token == null) {
            token = request.getHeader("authorization").split(" ")[1];
        }
        // 删除 token 以注销
        consumerTokenServices.revokeToken(token);
        return new ResponseResult<Void>(CodeStatus.OK, "用户已注销");
    }

    @GetMapping(value = "/user/info")
    public ResponseResult info() throws Exception {
        // 获取认证信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return new ResponseResult(CodeStatus.OK, userService.info(authentication.getName()));
    }

    @GetMapping("/user/menu/{system}")
    public ResponseResult menu(@PathVariable("system") String system) {
        // 获取认证信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return new ResponseResult(CodeStatus.OK,
                userService.getUserMenu(authentication.getName(), system));
    }
}
